package com.wanlian.netty.model;

import com.wanlian.util.StringUtil;
import io.netty.channel.ChannelId;

import java.util.HashMap;
import java.util.Map;

public class SessionPool {

    public Map<String, ChannelInfo> publicKeyChannelMap; //= new HashMap<String, ChannelId>();
    private Map<ChannelId, Session> sessionMap; //= new HashMap<ChannelId, Session>();

    public SessionPool() {
        publicKeyChannelMap = new HashMap<String, ChannelInfo>();
        sessionMap = new HashMap<ChannelId, Session>();
    }


    /**
     * 添加到session
     *
     * @param session
     */
    public void addSession(Session session) {
        if (!sessionMap.containsKey(session.getId())) {
            sessionMap.put(session.getId(), session);
            if (!publicKeyChannelMap.containsKey(session.getPublicKey())) {
                publicKeyChannelMap.put(session.getPublicKey(), new ChannelInfo(session.getId()));
            }
        }
    }


    /**
     * 重新注册
     *
     * @param session
     */
    public void changeSession(Session session) {
        if (publicKeyChannelMap.containsKey(session.getPublicKey())) {
            ChannelId id = publicKeyChannelMap.get(session.getPublicKey()).getChannelId();
            sessionMap.remove(id);
            publicKeyChannelMap.put(session.getPublicKey(), new ChannelInfo(session.getId()));
            sessionMap.put(session.getId(), session);
        }
    }

    public Map<ChannelId, Session> getAllSessionMap() {
        return sessionMap;
    }

    public Map<ChannelId, Session> getAllSessionMapExceptThis(ChannelId id) {
        Map<ChannelId, Session> sMap = new HashMap<ChannelId, Session>();
        for (ChannelId keyid : sessionMap.keySet()) {
            if (!keyid.equals(id)) {
                sMap.put(keyid, sMap.get(keyid));
            }
        }
        return sMap;
    }

    public Map<ChannelId, Session> getAllSessionMapThis(ChannelId id) {
        Map<ChannelId, Session> sMap = new HashMap<ChannelId, Session>();
        for (ChannelId keyid : sessionMap.keySet()) {
            if (keyid.equals(id)) {
                sMap.put(keyid, sMap.get(keyid));
            }
        }
        return sMap;
    }

    /**
     * getpmapToString
     *
     * @return
     */
    public String pmapToString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("[");
        for (String key : publicKeyChannelMap.keySet()) {
            stringBuilder.append("{key：" + key + ",channelid:" + publicKeyChannelMap.get(key) + "}");
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    /**
     * 通过channelId删除
     *
     * @param id
     */
    public synchronized String removeSessionByChannelId(ChannelId id) {
        if (sessionMap.containsKey(id)) {
            sessionMap.remove(id);
            String key = "";

            for (String pkey : publicKeyChannelMap.keySet()) {
                ChannelInfo id2 = publicKeyChannelMap.get(pkey);
                if (id2.getChannelId().equals(id)) {
                    key = pkey;
                    break;
                }
            }
            System.out.println("sessionpool remove key" + key);
            if (StringUtil.hasValue(key)) {
                publicKeyChannelMap.remove(key);
                return key;
            }
        }
        return null;
    }

    public synchronized Map<String, String> copyMap() {
        Map<String, String> maps = new HashMap<>();
        for (String key : publicKeyChannelMap.keySet()) {
            maps.put(key, key);
        }
        return maps;
    }

    /**
     * 通过key删除
     *
     * @param key
     */
    public synchronized void removeSessionByKey(String key) {
        if (publicKeyChannelMap.containsKey(key)) {
            ChannelInfo channelInfo = publicKeyChannelMap.get(key);
            if (sessionMap.containsKey(channelInfo.getChannelId())) {
                sessionMap.remove(channelInfo.getChannelId());
            }
            publicKeyChannelMap.remove(key);
        }
    }

    /**
     * 通过map删除
     *
     * @param map
     */
    public synchronized void removeSessionByMap(Map<String, String> map) {
        for (String key : map.keySet()) {
            if (publicKeyChannelMap.containsKey(key)) {
                ChannelInfo channelInfo = publicKeyChannelMap.get(key);
                System.out.println("Session Remove key:" + key);
                if (sessionMap.containsKey(channelInfo.getChannelId())) {
                    sessionMap.remove(channelInfo.getChannelId());
                }
                publicKeyChannelMap.remove(key);
            }
        }
    }

    /**
     * 通过key获取session
     *
     * @param publicKey
     * @return
     */
    public Session getSessionByPublicKey(String publicKey) {
        if (publicKeyChannelMap.containsKey(publicKey)) {
            ChannelInfo channelInfo = publicKeyChannelMap.get(publicKey);
            if (sessionMap.containsKey(channelInfo.getChannelId())) {
                return sessionMap.get(channelInfo.getChannelId());
            }
        }
        return null;
    }

    public boolean isExist(String publicKey) {
        if (publicKeyChannelMap.containsKey(publicKey)) {
            ChannelInfo channelInfo = publicKeyChannelMap.get(publicKey);
            if (sessionMap.containsKey(channelInfo.getChannelId())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 修改地址
     *
     * @param address
     */
    public void changeAddress(Address address) {
        if (publicKeyChannelMap.containsKey(address.getPublickey())) {
            ChannelId id = publicKeyChannelMap.get(address.getPublickey()).getChannelId();
            Session session = sessionMap.get(id);
            session.setAddress(address);
        }
    }

    /**
     * 获取地址
     *
     * @param publicKey
     */
    public Address getAddressByPublicKey(String publicKey) {
        if (publicKeyChannelMap.containsKey(publicKey)) {
            ChannelId id = publicKeyChannelMap.get(publicKey).getChannelId();
            if (sessionMap.containsKey(id)) {
                return sessionMap.get(id).getAddress();
            }
        }
        return null;
    }

    public Map<String, Address> getAllRouter() {
        Map<String, Address> routerMap = new HashMap<>();
        for (String key : publicKeyChannelMap.keySet()) {
            ChannelInfo channelInfo = publicKeyChannelMap.get(key);
            if (sessionMap.containsKey(channelInfo.getChannelId())) {
                Address address = sessionMap.get(channelInfo.getChannelId()).getAddress();
                if (address.isbRouter()) {
                    routerMap.put(key, address);
                }
            }
        }
        return routerMap;
    }



    public boolean isRouterPeer(String key){
        if(publicKeyChannelMap.containsKey(key)){
            ChannelInfo channelInfo=publicKeyChannelMap.get(key);
            if (sessionMap.containsKey(channelInfo.getChannelId())) {
                Address address = sessionMap.get(channelInfo.getChannelId()).getAddress();
                if (address.isbRouter()) {
                    return true;
                }
            }
        }
        return false;
    }


    public Map<String, String> getAllPeer() {
        Map<String, String> routerMap = new HashMap<>();
        for (String key : publicKeyChannelMap.keySet()) {
            ChannelInfo channelInfo = publicKeyChannelMap.get(key);
            if (sessionMap.containsKey(channelInfo.getChannelId())) {
                //Address address= sessionMap.get(channelInfo.getChannelId()).getAddress();
                routerMap.put(key, key);
            }
        }
        return routerMap;
    }

}
